package fm.yichenet.controller;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import fm.cache.GoodClassCache;
import fm.controller.BaseController;
import fm.dao.SolrBaseDao;
import fm.dto.NeiyiUser;
import fm.entity.WxUser;
import fm.exception.BizException;
import fm.exception.TokenInvalidException;
import fm.mongo.MCondition;
import fm.mongo.MRel;
import fm.mongo.MongoTable;
import fm.mongoService.UserService;
import fm.nio.SemaphoreExecutor;
import fm.web.CurrentRequest;
import fm.web.MediaTypes;
import fm.yichenet.mongo.service.ExpressService;
import fm.yichenet.mongo.service.GoodMgrService;
import fm.yichenet.mongo.service.ShopMgrService;
import fm.yichenet.mongo.service.VisitHistoryService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CountDownLatch;

/**
 * Created by CM on 17/5/31.
 */
@Controller
@RequestMapping("/good")
public class GoodController extends BaseController {
    private SemaphoreExecutor executor = new SemaphoreExecutor(30, "goodInfoQueryThread");
    @Autowired
    private ShopMgrService shopMgrService;
    @Autowired
    private UserService userService;
    @Autowired
    GoodMgrService goodMgrService;
    @Autowired
    VisitHistoryService visitHistoryService;
    @Autowired
    ExpressService expressService;


    @ResponseBody
    @RequestMapping("/list")
    public Map goodList(String goodName, Integer status, String shopId, String classId, String bigType,String[] classIds,
                        @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                        @RequestParam(required = false, defaultValue = "10") Integer pageSize, String orderField,
                        @RequestParam(value = "orderType", required = false, defaultValue = "1") Integer orderType,
                        String loc, Double distance) {
        Map res = new HashMap();
        try {
            Map param = new HashMap();


            try {
                NeiyiUser user = (NeiyiUser) CurrentRequest.getCurrentUser();
                if (user != null) {
                    DBObject log = new BasicDBObject();
                    if (StringUtils.isNotEmpty(goodName)) {
                        log.put("keyword", goodName);
                    }
                    if (StringUtils.isNotEmpty(classId)) {
                        log.put("good_class_id", classId);
                    }
                    if (StringUtils.isNotEmpty(bigType)) {
                        log.put("bigType", bigType);
                    }
                    log.put("visit_time", new Date());
                    log.put("shop_id", user.getId());
                    visitHistoryService.addVisitLog(log);
                }
            } catch (Exception ex) {
                LOGGER.error("获取用户登陆信息失败:", ex);
            }


            if (status != null) {
                param.put("status", status + "");
            }

            if (shopId != null) {
                param.put("shop_id", shopId);
            }

            if (StringUtils.isNotEmpty(goodName)) {
                param.put("goodName", goodName);
            }

            if (StringUtils.isNotEmpty(classId)) {
                param.put("good_class_id", classId);
            }

            if (StringUtils.isNotEmpty(loc)) {
                param.put("loc", loc);
            }
            if (StringUtils.isNotEmpty(bigType)) {
                param.put("bigType", bigType);
            }
            if (classIds!=null) {
                param.putAll(MCondition.create(MRel.in).append("good_class_id", classIds).toDBObject().toMap());
            }

            DBObject sort = null;
            if (StringUtils.isNotEmpty(orderField)) {
                sort = new BasicDBObject(orderField, orderType == 1 ? Sort.Direction.ASC.toString() : Sort.Direction.DESC.toString());
            }
            List result = goodMgrService.getList(param, pageNum, pageSize, sort);
            res.put("data", result);
            this.success(res);
        } catch (BizException ex) {
            LOGGER.error("occur business error", ex);
            this.failed(res, ex.getMessage());
        } catch (Exception ex) {
            LOGGER.error("occur un-expected error", ex);
            this.failed(res, "服务器发生未知错误，请稍后再试或者联系管理员解决！");
        }
        return res;
    }


    @ResponseBody
    @RequestMapping("/class/list")
    public Map goodClassList() {
        Map res = new HashMap();
        try {
            Map param = new HashMap();
            param.put("uuid", "123");
            DBObject all = shopMgrService.getGoodClassByUuid(param);

            res.put("data", all.get("list"));
            this.success(res);
        } catch (BizException ex) {
            LOGGER.error("occur business error", ex);
            this.failed(res, ex.getMessage());
        } catch (Exception ex) {
            LOGGER.error("occur un-expected error", ex);
            this.failed(res, "服务器发生未知错误，请稍后再试或者联系管理员解决！");
        }
        return res;
    }

    @ResponseBody
    @RequestMapping("/like/list")
    public Map likeGoodList(@RequestParam(value = "pageNum", defaultValue = "1", required = false) Integer pageNum,
                            @RequestParam(value = "pageSize", defaultValue = "10", required = false) Integer pageSize) {
        Map res = new HashMap();
        try {
            List goods = visitHistoryService.getLikeGoodListOfVisitLog(pageNum, pageSize);
            res.put("data", goods);
            this.success(res);
        } catch (BizException ex) {
            LOGGER.error("occur business error", ex);
            this.failed(res, ex.getMessage());
        } catch (Exception ex) {
            LOGGER.error("occur un-expected error", ex);
            this.failed(res, "服务器发生未知错误，请稍后再试或者联系管理员解决！");
        }
        return res;
    }


    /**
     * 获取商品信息
     *
     * @param goodId
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "/info", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public Map goodInfo(@RequestParam(value = "goodId", required = true) String goodId) throws Exception {
        Map<String, Object> res = new HashedMap();
        Map<String, Object> params = new HashedMap();
        params.put("good_id", goodId);
        DBObject good = goodMgrService.getGood(params);
        if (good != null) {
            Long goodClassId = Long.parseLong("" + good.get("good_class_id"));
            //TODO 商品价格是否显示为0 要根据类别是否开启了隐藏价格 如果开启了此属性，该类商品的价格全部显示为零 ，订单流程也要按照待改价的商品来处理
            if (GoodClassCache.isHidePrice(goodClassId)) {
                good.put("sale_price", 0);
                good.put("source_price", 0);
            }
        }
        if (!"1".equals(String.valueOf(good.get("status")))) {
            this.failed(res, "商品已下架");
            return res;
        }

        try {
            WxUser user = (WxUser) CurrentRequest.getCurrentUser();
            if (user != null) {
                DBObject log = new BasicDBObject();
                log.put("good_class_id", good.get("good_class_id"));
                log.put("shop_id", good.get("shop_id"));
                log.put("bigType", good.get("bigType"));
                log.put("visit_time", new Date());
                log.put("user_id", user.getId());
                visitHistoryService.addVisitLog(log);
            }
        } catch (TokenInvalidException ex) {
        } catch (Exception ex) {
            LOGGER.error("获取用户登陆信息失败:", ex);
        }

        //获取评论的相关数据
        good.put("comments_count", goodMgrService.facetCommentLevel(goodId));
        good.put("comments_preview", goodMgrService.getGoodCommentListForPage(params, 5, 1));
        res.put("data", good.toMap());
        this.success(res);
        return res;
    }

    /**
     * 商品评论列表
     *
     * @param pageSize
     * @param pageNum
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/comment/list", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public Map goodCommentsListForPage(@RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize,
                                       @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
                                       @RequestParam(value = "goodId", required = true) String goodId,
                                       @RequestParam(value = "level", required = true) Integer level) throws Exception {
        Map<String, Object> res = new HashedMap();
        Map<String, Object> params = new HashedMap();
        params.put("good_id", goodId);
        params.put("level", level);
        List list = goodMgrService.getGoodCommentListForPage(params, pageSize, pageNum);
        res.put("data", list);
        this.success(res);
        return res;
    }

    /**
     * 评论商品
     *
     * @param params
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/comment/add", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public Map goodComment(@RequestBody Map params) throws Exception {
        Map<String, Object> res = new HashedMap();
        try {
            NeiyiUser user = (NeiyiUser) getCurrentUser();
            Map data = goodMgrService.goodComment(params, user);
            res.put("data", data);
            this.success(res);
        } catch (BizException ex) {
            this.failed(res, ex);
        }

        return res;
    }

    /**
     * 商品发布
     *
     * @param good
     * @return
     */
    @ResponseBody
    @RequestMapping("/publish")
    public Map goodPublish(@RequestBody Map good) {
        Map res = new HashMap();
        try {
            WxUser user = (WxUser) CurrentRequest.getCurrentUser();
            if (user.getReviewStatus() != 2) {
                throw new BizException("您的认证资料尚未通过审核无法发布商品，请耐心等待，或者联系平台客服了解进度！");
            }
            Map param = getEmptyParamMap();
            param.put("shop_id", getCurrentUserId());
            param.putAll(good);
            param.put("priority", 0);
            param.put("good_id", UUID.randomUUID().toString().replaceAll("-", ""));
            BigDecimal lat = user.getLatitude();
            BigDecimal lon = user.getLongitude();
            if (lat == null || lon == null) {
                throw new BizException("您的店铺尚未提交实体店地址经纬度，请先配置店铺地址后再发布商品！");
            }
            double latd = lat != null ? lat.doubleValue() : 0d;
            double lngd = lon != null ? lon.doubleValue() : 0d;

            param.put("loc", Math.min(latd, lngd) + "," + Math.max(latd, lngd));
            param.put("address", user.getCity() + "·" + user.getDistrict());
            param.put("status", 1 + "");

            goodMgrService.addGood(param);
            this.success(res);
        } catch (BizException ex) {
            LOGGER.error("occur business error", ex);
            this.failed(res, ex.getMessage());
        } catch (Exception ex) {
            LOGGER.error("occur un-expected error", ex);
            this.failed(res, "服务器发生未知错误，请稍后再试或者联系管理员解决！");
        }
        return res;
    }
}
